package com.tensquare.user.aspect;

import com.alibaba.fastjson.JSON;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;
import com.tensquare.constants.TokenConstants;
import com.tensquare.entity.JWTInfo;
import com.tensquare.exception.PreAuthorizeException;
import com.tensquare.exception.UserTokenException;
import com.tensquare.user.annotation.PreAuthorize;
import com.tensquare.user.utils.JWTUtil;
import com.tensquare.user.vo.Permission;
import com.tensquare.user.vo.UserInfoResponse;
import com.tensquare.util.JwtTokenUtil;
import com.tensquare.util.RedisConstant;
import com.tensquare.util.StringHelper;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Aspect
@Component
public class PreAuthorizeAspect {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Around("@annotation(com.tensquare.user.annotation.PreAuthorize)")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        PreAuthorize annotation = methodSignature.getMethod().getAnnotation(PreAuthorize.class);
        String methodName = methodSignature.getMethod().getName();
        if (null == annotation) return joinPoint.proceed();
        if (!StringHelper.isEmpty(annotation.hasPermission())){
            if (!hasPermission(annotation.hasPermission())){
                log.info("methodName->{}",methodName);
                throw new PreAuthorizeException("无权限访问");
            }
        }

        return joinPoint.proceed();
    }

    public boolean hasPermission(String per) throws Exception {
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = servletRequestAttributes.getRequest();
        String token = request.getHeader(TokenConstants.TOKEN_VALUE);
        Claims claims = JwtTokenUtil.getInfoFromToken(token, TokenConstants.SECRET_KEY);
        JWTInfo jwtInfo = new JWTUtil().getJWTInfo(claims);
        String s = redisTemplate.opsForValue().get(RedisConstant.REDIS_USER_INFO_KEY + ":" + jwtInfo.getId());
        try {
            UserInfoResponse userInfoResponse = new Gson().fromJson(s, UserInfoResponse.class);
            for (Permission permission : userInfoResponse.getPermissions()) {
                if (per.equals(permission.getPerCode())) {
                    return true;
                }
            }
        } catch (JsonSyntaxException e) {
            e.printStackTrace();
        }

        return false;
    }

}
